package com.hougong.lineclient.utils;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import java.util.Arrays;
import java.util.Calendar;

public  final class NumberUtils {
    public static short getUint8(byte s) {
        return (short) (s & 0x00ff);
    }

    public static int getUint16(short s) {
        return (int) (s & 0x0000ffff);
    }

    public static long getUint32(int s) {
        return (long) (s & 0x00000000ffffffff);
    }


    private NumberUtils() {

    }

    /**
     * 比如 2018 --> 0x2018
     *
     * @param n
     * @return
     */
    public static int numberToBCD(int n) {
        int s = 0;
        int m = 1;
        int a = 0;
        while (n != 0) {
            a = n % 10;
            s = s + a * m;
            m = m * 16;
            n = n / 10;
        }
        return s;
    }

    /**
     * 比如 0x2018--->2018
     *
     * @param bcd
     * @return
     */
    public static int bcdToNumber(int bcd) {
        System.out.println("bcd"+bcd);
        int n = 0; //后面的4bit
        int s = 0;
        int i = 1; // 进位
        while (bcd != 0) {
            n = bcd & 0xf;
            System.out.println("n=" + n);
            bcd = bcd >>> 4;
            s = s + n * i;
            System.out.println("s=" + s + " n*i=" + n + "*" + i);
            i = i * 10;
        }
        System.out.println("s"+s);

        return s;
    }

    /**
     * 将byte转换为一个长度为8的byte数组，数组每个值代表bit
     *   高位在前 地位在后
     */
    public static byte[] getByteBitArray(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >>> 1);
        }
        return array;
    }

    /**
     * 获取bcd 码的当前时间YYYYMMDDHHmmss
     *
     * @return
     */
    public static byte[] getBcdCurrentTime_7_yyyyMMddHHmmss() {
        Calendar instance = Calendar.getInstance();
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH) + 1;
        int day = instance.get(Calendar.DAY_OF_MONTH);
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        int min = instance.get(Calendar.MINUTE);
        int sec = instance.get(Calendar.SECOND);
        System.out.println(" "+year+" "+month+" "+day+" "+hour+" "+min+" "+sec);
        ByteBuf byteBuf = Unpooled.buffer();
        byteBuf.writeShort(NumberUtils.numberToBCD(year))
                .writeByte(NumberUtils.numberToBCD(month))
                .writeByte(NumberUtils.numberToBCD(day))
                .writeByte(NumberUtils.numberToBCD(hour))
                .writeByte(NumberUtils.numberToBCD(min))
                .writeByte(NumberUtils.numberToBCD(sec));
        byte[] body = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(body);
        byteBuf.release();
        return body;
    }


    /**
     * 获取bcd 码的当前时间YYYYMMDDHHmm
     *
     * @return
     */
    public static byte[] getBcdCurrentTime_6_yyyyMMddHHmm() {
        Calendar instance = Calendar.getInstance();
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH) + 1;
        int day = instance.get(Calendar.DAY_OF_MONTH);
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        int min = instance.get(Calendar.MINUTE);
        ByteBuf byteBuf = Unpooled.buffer();
        byteBuf.writeShort(NumberUtils.numberToBCD(year))
                .writeByte(NumberUtils.numberToBCD(month))
                .writeByte(NumberUtils.numberToBCD(day))
                .writeByte(NumberUtils.numberToBCD(hour))
                .writeByte(NumberUtils.numberToBCD(min));
        byte[] body = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(body);
        byteBuf.release();
        return body;
    }

    /**
     * 获取bcd 码的当前时间YYMMDDHHmmss
     *
     * @return
     */
    public static byte[] getBcdCurrentTime_6_2() {
        Calendar instance = Calendar.getInstance();
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH) + 1;
        int day = instance.get(Calendar.DAY_OF_MONTH);
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        int min = instance.get(Calendar.MINUTE);
        int sec = instance.get(Calendar.SECOND);
        ByteBuf byteBuf = Unpooled.buffer();
        byteBuf.writeByte(NumberUtils.numberToBCD(year % 100))
                .writeByte(NumberUtils.numberToBCD(month))
                .writeByte(NumberUtils.numberToBCD(day))
                .writeByte(NumberUtils.numberToBCD(hour))
                .writeByte(NumberUtils.numberToBCD(min))
                .writeByte(NumberUtils.numberToBCD(sec));
        byte[] body = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(body);
        byteBuf.release();
        return body;
    }

    /**
     * 获取指定日期的7位BCD字节数组 YYYYMMDDHHmmss
     *
     * @param year
     * @param month 从1开始
     * @param day
     * @param hour
     * @param min
     * @param sec
     * @return
     */
    public static byte[] getBcdTime_7_yyyyMMddHHmmss(int year, int month, int day, int hour, int min, int sec) {
        ByteBuf byteBuf = Unpooled.buffer();
        byteBuf.writeShort(NumberUtils.numberToBCD(year))
                .writeByte(NumberUtils.numberToBCD(month))
                .writeByte(NumberUtils.numberToBCD(day))
                .writeByte(NumberUtils.numberToBCD(hour))
                .writeByte(NumberUtils.numberToBCD(min))
                .writeByte(NumberUtils.numberToBCD(sec));
        byte[] body = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(body);
        byteBuf.release();
        return body;
    }

    public static byte[] getBcdTime_7_yyyyMMddHHmmss(Calendar instance){
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH) + 1;
        int day = instance.get(Calendar.DAY_OF_MONTH);
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        int min = instance.get(Calendar.MINUTE);
        int sec = instance.get(Calendar.SECOND);
        ByteBuf byteBuf = Unpooled.buffer();
        byteBuf.writeByte(NumberUtils.numberToBCD(year % 100))
                .writeByte(NumberUtils.numberToBCD(month))
                .writeByte(NumberUtils.numberToBCD(day))
                .writeByte(NumberUtils.numberToBCD(hour))
                .writeByte(NumberUtils.numberToBCD(min))
                .writeByte(NumberUtils.numberToBCD(sec));
        byte[] body = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(body);
        byteBuf.release();
        return body;
    }

    public static byte[] getBcdTime_6(int year, int month, int day, int hour, int min) {
        ByteBuf byteBuf = Unpooled.buffer();
        byteBuf.writeShort(NumberUtils.numberToBCD(year))
                .writeByte(NumberUtils.numberToBCD(month))
                .writeByte(NumberUtils.numberToBCD(day))
                .writeByte(NumberUtils.numberToBCD(hour))
                .writeByte(NumberUtils.numberToBCD(min));
        byte[] body = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(body);
        byteBuf.release();
        return body;
    }

    public static byte ascII2Bcd(byte asc) {
        if ((asc >= '0') && (asc <= '9'))
            return (byte) (asc - '0');
        else if ((asc >= 'A') && (asc <= 'F'))
            return (byte) (asc - 'A' + 10);
        else if ((asc >= 'a') && (asc <= 'f'))
            return (byte) (asc - 'a' + 10);
        else
            return (byte) (asc - 48);
    }

    public static void ConvertToASCII(String string) {
        StringBuilder sb = new StringBuilder();
        char[] ch = string.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            sb.append(Integer.valueOf(ch[i]).intValue()).append("  ");
        }
        System.out.println(sb.toString());
    }

    /**
     * 设置32位类型的数的 某个位置的bit位0
     *
     * @param bitIndex 从0开始计算
     * @param src      需要修改的数
     */
    public static int set32IntBit0(int bitIndex, int src) {
        return (~(1 << bitIndex)) & src;
    }

    /**
     * 设置32位类型的数的 某个位置的bit为1
     *
     * @param bitIndex
     * @param src
     */
    public static int set32IntBit1(int bitIndex, int src) {
        return (1 << bitIndex) | src;
    }



    /**
     * int 转 字节数组，就是里面的字节内容一样 ，不管正负
     * @param res
     * @return
     */
    public static byte[] intToByte(int res) {

        byte[] targets = new byte[4];

        targets[3] = (byte) (res & 0xff);//最低位

        targets[2] = (byte) ((res >> 8) & 0xff);//次低位

        targets[1] = (byte) ((res >> 16) & 0xff);//次高位

        targets[0] = (byte) (res >>> 24);//最高位,无符号右移。

        return targets;
    }

    /**
     * 字节数组转int  只保证从前往后的前4个字节做转化
     * @param res
     * @return
     */
    public static int byteToInt(byte[] res) {
        int value = 0;
        int len=res.length;
        if(len==4){
            value =(res[3] & 0xff
                    | ((res[2] & 0xff) << 8)
                    | ((res[1] & 0xff) << 16)
                    | (res[0] & 0xff) << 24);
        }else if (len==2){
            value=((res[1]&0xff)<<8)|((res[0]&0xff));
        }else  if(len==1){
            value=(res[0])&0xff;
        }else{
            System.out.println("####  byte2int 转化错误 !!!###########");
        }
        return value;
    }

    public static byte[] shortToByte(short number) {
        byte[] b = new byte[2];
        b[1] = (byte) (number & 0xff);
        b[0]= (byte) ((number>>8)&0xff);
        return b;
    }

    public static short byteToShort(byte[] b) {
        short s = 0;
        short s0 = (short) (b[1] & 0xff);// 最低位
        short s1 = (short) (b[0] & 0xff);
        s1 <<= 8;
        s = (short) (s0 | s1);
        return s;
    }

    /**
     * 获取协议定义的时间戳id
     * @param year
     * @param month
     * @param day
     * @param hour
     * @param min
     * @param sec
     * @return
     */
    public static  int getTimeStampId(int year,int month,int day,int hour,int min,int sec){
        return  ((year-2000)<<26)|(month<<22)|(day<<17)|(hour<<12)|(min<<6)|(sec<<0);
    }
    public static int  getCurrentTimeStampId(){
        Calendar instance = Calendar.getInstance();
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH) + 1;
        int day = instance.get(Calendar.DAY_OF_MONTH);
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        int min = instance.get(Calendar.MINUTE);
        int sec = instance.get(Calendar.SECOND);
        return getTimeStampId(year,month,day,hour,min,sec);
    }

    public void   getTimeStamp(int timeStampId){
       int year=timeStampId>>26;
       int month=timeStampId&(0b00000011110000000000000000000000)>>>22;
       int day=timeStampId&(0b00000000001111100000000000000000)>>>17;
       int hour=timeStampId&(0b000000000000000011111000000000000)>>>12;
       int min=timeStampId&(0b00000000000000000000111111000000)>>>6;
       int sec=timeStampId&(0b00000000000000000000000000111111)>>>0;
        System.out.println(year+"年"+month+"月"+day+"时"+hour+"时"+min+"分"+sec+"秒");
    }

    /**
     * 不足 needLen 位 则右补0x00
     * @param src
     * @param needLen
     * @return
     */
    public static  byte[] rightPad00(byte[] src,int needLen){
        if(src==null){
            return null;
        }
        int srcLen=src.length;
        if(srcLen<needLen){
            int difLen=needLen-srcLen;
            byte[] append=new byte[difLen];
            for (int i=0;i<difLen;i++){
                append[i]=0x00;
            }
           src= Arrays.copyOf(src,needLen);
            System.arraycopy(append,0,src,srcLen,difLen);
        }
        return src;
    }

    public static byte[] getFilledBytes(int len,byte fill){
        byte[] bytes=new byte[len];
        for(int i=0;i<len;i++){
            bytes[i]=fill;
        }
        return bytes;
    }
    public static byte[] getZeroBytes(int len){
        return getFilledBytes(len, (byte) 0);
    }
}
